package com.baitiaojun.api.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * @类名 TokenUtil
 * @描述
 * @作者 白条君
 * @创建日期 2022/10/26 16:12
 * @版本 1.0
 */
public class TokenUtil {

    public static String generateToken(Long userId, Enum<ConstantUtil.TokenType> type) throws Exception {
        Algorithm algorithm = Algorithm.RSA256(RSAUtil.getPublicKey(), RSAUtil.getPrivateKey());
        //LocalDate在多线程下是线程安全的
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime expires = type.equals(ConstantUtil.TokenType.ACCESS)? now.plus(ConstantUtil.ACCESS_TOKEN_TIMEOUT, ChronoUnit.DAYS) : now.plus(ConstantUtil.REFRESH_TOKEN_TIMEOUT, ChronoUnit.DAYS);
        return JWT.create()
                //载荷部分创建用户身份标识、签名发布者、token过期时间、token发布时间
                .withKeyId(String.valueOf(userId))
                .withIssuer(ConstantUtil.ISSUER)
                .withExpiresAt(Date.from(expires.atZone(ZoneId.systemDefault()).toInstant()))
                .withIssuedAt(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()))
                //头部指定使用RSA256算法对token进行加密和解码
                .sign(algorithm);
    }

    public static Long verifyToken(String token) throws Exception {
        Algorithm algorithm = Algorithm.RSA256(RSAUtil.getPublicKey(), RSAUtil.getPrivateKey());
        JWTVerifier verifier = JWT.require(algorithm).build();
        DecodedJWT verify = verifier.verify(token);
        String id = verify.getKeyId();
        return Long.valueOf(id);
    }

    public static boolean isExpiresToken(String token) throws Exception {
        Algorithm algorithm = Algorithm.RSA256(RSAUtil.getPublicKey(), RSAUtil.getPrivateKey());
        JWTVerifier verifier = JWT.require(algorithm).build();
        try {
            verifier.verify(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public static void main(String[] args) throws Exception {
        System.out.println(generateToken(123456L, ConstantUtil.TokenType.ACCESS));
    }
}